/* SNDCONF.C
 * sound configuration routines/menus
 * originally this used to be external program,
 * later moved in main exe
 *************
 * 29.08.2000 : Toni R„s„nen
 *              modifications/documentation for open source
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include "gfx2.h"
#include "mpack.h"
#include "mixer.h"
#include "mod.h"
#include "pakfile.h"
#include "mainmenu.h"
#include "keys.h"
#include "sound.h"
#include "sndconf.h"
#include "version.h"

typedef struct {  char items;
                  char menutitle[30];
                  char text[6][20];
                  int setvalue[6];
                  char reset;
               } menuitem;

menuitem ioconfigmenu = { 6,
                          "Select IO address",
                          {"210","220","230","240","250","260"},
                          {0x210, 0x220, 0x230, 0x240, 0x250, 0x260},  1 };

menuitem irqconfigmenu = { 3,
                           "Select IRQ",
                           {"IRQ 5","IRQ 7","IRQ 11","IRQ 666","IRQ 0","IRQ HELL"},
                           {5,7,11,0,0,0},  1 };

menuitem dmaconfigmenu = { 2,
                           "Select DMA channel",
                           {"DMA 1","DMA 3","","","",""},
                           {1,3,0,0,0,0},  1 };

menuitem hdmaconfigmenu = { 2,
                            "Select high DMA channel",
                            {"DMA 4","DMA 5","","","",""},
                            {4,5,0,0,0,0},  1 };

menuitem mixingmenu = { 4,
                        "Select mixing frequency",
                        {"Automatic","11025","22050","44100","128kbps MP3","WAV"},
                        {0,11025,22050,44100,0,0},  1 };

menuitem interpmenu = { 2,
                        "Select interpolation",
                        {"Enabled","Disabled","","","",""},
                        {1,0, 0,0,0,0},  0 };

menuitem devicemenu = { 2,
                        "Use mono mixing",
                        {"Use mono","Use stereo","","","",""},
                        {2,3, 0,0,0,0},  0 };

menuitem force8bitmenu = { 2,
                        "Force 8-bit mixing",
                        {"Use 16 bit","Use 8 bit","","","",""},
                        {0,1, 0,0,0,0},  0 };

menuitem sblivemenu = { 2,
                        "Use SB LIVE's 16-bit mixing",
                        {"Use LIVE mixing","Use standard mixing","","","",""},
                        {1,0, 0,0,0,0},  0 };

int restarts;

//int sndio,snddma,sndhighdma,sndirq;
//int use_interpolation
//int force_mixfreq
//int unsigned16bit
//int mix_stereo
//int disable_16bitmix
int use_device; // 2=mono, 3=stereo, 0=none

int autodetect(int *sndio, int *snddma, int *sndhighdma, int *sndirq)
{  char *env;
   char b,i,n,c;

   env = getenv ("BLASTER");
   if (env == NULL)
     return -1;
   *sndio = *sndhighdma = *snddma = *sndirq = 0; // 220
   i = 0;
   while ( (b = *(env+i++)) != 0 )
     {  if (b == 'A')
           { *sndio = ( *(env+i+1) - 0x30 ) << 4;
             *sndio += 0x200;
           } // if b=A
        if (b == 'D')
           { switch (*(env+i++))
                { case '0': { *snddma = 0; break; }
                  case '1': { *snddma = 1; break; }
                  case '3': { *snddma = 3; break; }
                }
           } //if b=D
        if (b == 'H')
           { switch (*(env+i++))
               { case '5': { *sndhighdma = 5; break; }
                 case '6': { *sndhighdma = 6; break; }
                 case '7': { *sndhighdma = 7; break; }
               }
           } //if b=H
        if (b == 'I')
           { switch (*(env+i++))
               { case '2': { *sndirq = 2; break; }
                 case '5': { *sndirq = 5; break; }
                 case '7': { *sndirq = 7; break; }
                 case '9': { *sndirq = 9; break; }
                 case '1': { switch (*(env+i++))
                              { case '0' : { *sndirq = 10; break; }
                                case '1' : { *sndirq = 11; break; }
                              }
                              break;
                           }
               }
           } //if b=D
     }
}


void reset_soundsystem()
{  mod_release();
   release_sounds();
   close_sound();
   if (use_device == 0) return;

   init_mixer (use_device, sndio, sndirq, snddma, sndhighdma, 20);
}

void makeconfline (int val, int radix)
{  if (val == 0)
     strcpy (rivi,"n/a");
   else
     itoa (val, rivi, radix);
}

void print_submenu(menuitem *menu, int sel)
{  int i,y;
   y = 60;
   for (i = 0; i < menu->items; i++)
     {  writesel ( sel-1,i, menu->text[i]);
        writemid ( 160,y, rivi);
        y += 10;
     }
}

void submenu(menuitem *menu, int *value)
{  int i,sel,changed;

   sel = 1;
   for (i = 0; i <= menu->items; i++)
     if (*value == menu->setvalue[i])
       { sel = i+1; break; }


   changed = 1;
   while (1)
     {  if (changed)
          {  memmove (ruutu, ruutu2, 64000);
             writemid (160,10,"Sound Configuration");
             writemid (160,45,menu->menutitle);
             print_submenu (menu,sel);
             flip();
             changed = 0;
          }

        if ( (keybuffer[72]) && (sel > 1) )
          {  keybuffer[72] = 0; changed++; sel--; }
        if ( (keybuffer[80]) && (sel < menu->items) )
          {  keybuffer[80] = 0; changed++; sel++; }

        if (keybuffer[1])
          {  keybuffer[1] = 0; break; }

        if (keybuffer[28])
          {  *value = menu->setvalue[sel-1];
             keybuffer[28] = 0;
             if (menu->reset)
               {  mod_release();
                  release_sounds();
                  close_sound(); // modifying these require hw reset
               }
             break;
          }
     }
}

void display_current_soundconfig(int sel)
{

   writeselc (sel==1, 40,"Autodetect","");
   writeselc (sel==2, 50,"Disable sounds","");
   writeselc (sel==3, 60,"Accept configuration","");

   makeconfline (sndio, 16);
   writeselc (sel==4, 70,"IO Address:",rivi);

   makeconfline (sndirq, 10);
   writeselc (sel==5, 80,"Interrupt:",rivi);

   makeconfline (snddma, 16);
   writeselc (sel==6, 90,"DMA Channel:",rivi);

   makeconfline (sndhighdma, 16);
   writeselc (sel==7,100,"High DMA:",rivi);

   if (force_mixfreq == 0)
     strcpy (rivi,"Automatic");
   else
     itoa (force_mixfreq, rivi, 10);
   writeselc (sel==8,110,"Mixing Frequency:",rivi);

   if (use_interpolation)
     strcpy (rivi,"Enabled");
   else
     strcpy (rivi,"Disabled");
   writeselc (sel==9,120,"Interpolation:",rivi);

   if (use_device == 3)
     strcpy (rivi,"Enabled");
   else
     strcpy (rivi,"Disabled");
   writeselc (sel==10,130,"Stereo:",rivi);

   if (disable_16bitmix)
     strcpy (rivi,"Enabled");
   else
     strcpy (rivi,"Disabled");
   writeselc (sel==11,140,"Force 8-bit:",rivi);

   if (unsigned16bit)
     strcpy (rivi,"Enabled");
   else
     strcpy (rivi,"Disabled");
   writeselc (sel==12,150,"Force SB LIVE!:",rivi);
   
}

/*
void store_soundconfig()
{  FILE *tied;
   tied = fopen ("sound.cfg","wb");

   fwrite (&sndio, 4,1, tied);
   fwrite (&snddma, 4,1, tied);
   fwrite (&sndhighdma, 4,1, tied);
   fwrite (&sndirq, 4,1, tied);

   fwrite (&use_interpolation, 4,1, tied);
   fwrite (&disable_16bitmix, 4,1, tied);
   fwrite (&use_device, 4,1, tied);
   fwrite (&unsigned16bit,4,1, tied);

   fclose (tied);
}
*/


void set_sound_configuration()
{  int changed,sel;
   purakuva ("soundcfg.dat", ruutu2);
   setpale (64,64,64);

   changed = 1; sel = 1;
   while (1)
     {  if (changed)
          {  memmove (ruutu, ruutu2, 64000);
             writemid (160,10,"Sound Configuration");
             display_current_soundconfig(sel);
             flip();
             changed = 0;
          }

        if ( (keybuffer[72]) && (sel > 1) )
          {  keybuffer[72] = 0;
             sel--; changed++;
          }
        if ( (keybuffer[80]) && (sel < 12) )
          {  keybuffer[80] = 0;
             sel++; changed++;
          }

        if (keybuffer[28])
          {  keybuffer[28] = 0;
             if (sel == 3) break;
             changed++;
             switch (sel)
               {  case  1 : autodetect (&sndio, &snddma, &sndhighdma, &sndirq);
                            use_interpolation = 1;
                            disable_16bitmix = 0;
                            use_device = 3;
                            unsigned16bit = 0;
                            break;
                  case  2 : use_device = 0;
                            sndio = snddma = sndhighdma = sndirq = 0;
                            break;
                  case  4 : submenu (&ioconfigmenu,&sndio);
                            break;
                  case  5 : submenu (&irqconfigmenu,&sndirq);
                            break;
                  case  6 : submenu (&dmaconfigmenu,&snddma);
                            break;
                  case  7 : submenu (&hdmaconfigmenu,&sndhighdma);
                            break;
                  case  8 : submenu (&mixingmenu,&force_mixfreq);
                            break;
                  case  9 : submenu (&interpmenu,&use_interpolation);
                            break;
                  case 10 : submenu (&devicemenu,&use_device);
                            break;
                  case 11 : submenu (&force8bitmenu,&disable_16bitmix);
                            break;
                  case 12 : submenu (&sblivemenu,&unsigned16bit);
                            break;
               }
          }

        if (keybuffer[1])
          {  keybuffer[1] = 0; break; }
     }
   memset (ruutu,0,64000); flip(); // no color errors
   
//   store_soundconfig();
   reset_soundsystem();
}


void load_sound_configuration()
{  FILE *tied;
   tied = fopen ("game.cfg", "rb");
   if (tied == NULL)
     {  autodetect (&sndio, &snddma, &sndhighdma, &sndirq);
        use_interpolation = 1;
        disable_16bitmix = 0;
        use_device = 3;
        unsigned16bit = 0;

        set_sound_configuration();
        return;
     }
   fclose (tied);

   load_config();
     
   reset_soundsystem();
}

   /*
int main()
{  open_package ("gameg.pkg");
   ruutu = (char*) malloc (64000);
   ruutu2 = (char*) malloc (64000);

   spritedest = ruutu;

   set320();

   initkeys();

   load_font ("med.f", 1, 16384);

   load_sound_configuration();

   disablekeys();

   modvolume = 64;
   mod_load ("battlest.s3m");

   mod_start();

   getch();

   close_mixer();

   textmode (3);
}*/

extern int joymidx[2],joymidy[2];
extern int joydivx[2],joydivy[2];

void load_config()
{  int i;
   FILE *tied;
   tied = fopen ("game.cfg", "rb");

   fread (&i, 4,1, tied);
   if (i < CONFIGFILE_VERSION)
     { fclose (tied); return; }

   fread (&sndio, 4,1, tied);
   fread (&snddma, 4,1, tied);
   fread (&sndhighdma, 4,1, tied);
   fread (&sndirq, 4,1, tied);

   fread (&use_interpolation, 4,1, tied);
   fread (&disable_16bitmix, 4,1, tied);
   fread (&use_device, 4,1, tied);
   fread (&unsigned16bit,4,1, tied);
   fread (&force_mixfreq,4,1, tied);

   fread (plrkeys, sizeof(plrkeys),1, tied);
   fread (controltype, sizeof(controltype),1, tied);

   fread ( joymidx, 1,sizeof(joymidx), tied);
   fread ( joymidy, 1,sizeof(joymidy), tied);
   fread ( joydivx, 1,sizeof(joydivx), tied);
   fread ( joydivy, 1,sizeof(joydivy), tied);

   fread ( &restarts,1,4, tied);
   restarts++;

   fread ( &modvolume, sizeof(int),1, tied);
   fread ( &sfxvolume, sizeof(int),1, tied);
   
   fclose (tied);
}


void store_config()
{  int i;
   FILE *tied;
   tied = fopen ("game.cfg", "wb");

   i = CONFIGFILE_VERSION;
   fwrite (&i, 4,1, tied);

   fwrite (&sndio, 4,1, tied);
   fwrite (&snddma, 4,1, tied);
   fwrite (&sndhighdma, 4,1, tied);
   fwrite (&sndirq, 4,1, tied);

   fwrite (&use_interpolation, 4,1, tied);
   fwrite (&disable_16bitmix, 4,1, tied);
   fwrite (&use_device, 4,1, tied);
   fwrite (&unsigned16bit,4,1, tied);
   fwrite (&force_mixfreq,4,1, tied);

   fwrite (plrkeys, sizeof(plrkeys),1, tied);
   fwrite (controltype, sizeof(controltype),1, tied);

   fwrite ( joymidx, 1,sizeof(joymidx), tied);
   fwrite ( joymidy, 1,sizeof(joymidy), tied);
   fwrite ( joydivx, 1,sizeof(joydivx), tied);
   fwrite ( joydivy, 1,sizeof(joydivy), tied);

   fwrite ( &restarts,1,4, tied);

   fwrite ( &modvolume, sizeof(int),1, tied);
   fwrite ( &sfxvolume, sizeof(int),1, tied);
   
   fclose (tied);
}

